/**
 * @file engineer_mode_audio_calibration.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_watch.h"

#if USE_LV_WATCH_ENGINEER_MODE!= 0

/*********************
 *      DEFINES
 *********************/
#define ENGINEER_MODE_AUDIO_CALIBRATION_LIST_CNT    2

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static lv_engineer_audio_calibration_obj_ext_t * audio_calibration_get_ext(void);
static void audio_calibration_btn_rel_event_cb(lv_obj_t * btn, lv_event_t e);
static void audio_calibration_prepare_destory(lv_obj_t * activity_obj);

static void recording_test_create(lv_obj_t * par);
static void recording_start_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void recording_stop_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void recording_play_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void recording_end_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void recording_test_prepare_destory(lv_obj_t * activity_obj);
static void recording_test_record_cb(MCI_EVNET_T event, MCI_INFO_T info_type, int32_t value);
static void audio_calibration_record_file_over_cb(void * para);

static void playback_test_create(lv_obj_t * par);
static void playback_start_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void playback_stop_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void playback_test_prepare_destory(lv_obj_t * activity_obj);
static void audio_calibration_music_over_cb(void * para);

/**********************
 *  STATIC VARIABLES
 **********************/
const lv_engineer_item_t engineer_mode_audio_calibration_list[] = {
    { WATCH_TEXT_ID_EMODE_AUDIO_CAL_RECORDING_TEST, recording_test_create, recording_test_prepare_destory },
    { WATCH_TEXT_ID_EMODE_AUDIO_CAL_PLAYBACK_TEST, playback_test_create, playback_test_prepare_destory },
};

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
***********************/
lv_obj_t * engineer_mode_audio_calibration_create(lv_obj_t * activity_obj)
{
    lv_obj_t * obj;
    if(activity_obj == NULL) {
        lv_watch_activity_ext_t activity_ext;
        memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_ENGINEER_MODE_AUDIO_CALIBRATION;
        activity_ext.create = engineer_mode_audio_calibration_create;
        activity_ext.prepare_destory = audio_calibration_prepare_destory;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
        LV_ASSERT_MEM(activity_obj);
        if(NULL == activity_obj) {
            return NULL;
        }
    }

    obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);
    if(NULL == obj) {
        return NULL;
    }

    printf("%s watch_obj %p\n", __FUNCTION__, activity_obj);

    /*Allocate the object type specific extended data*/
    lv_engineer_audio_calibration_obj_ext_t * audio_ext = lv_obj_allocate_ext_attr(activity_obj, sizeof(lv_engineer_audio_calibration_obj_ext_t));
    LV_ASSERT_MEM(audio_ext);
    if(NULL == audio_ext) {
        return NULL;
    }
    memset((char *)audio_ext + sizeof(lv_watch_activity_ext_t), 0, sizeof(lv_engineer_audio_calibration_obj_ext_t) - sizeof(lv_watch_activity_ext_t));

    lv_obj_t * title = lv_label_create(obj, NULL);
    lv_obj_set_size(title, LV_HOR_RES, LV_VER_RES / 4);
    lv_label_set_text_id(title, WATCH_TEXT_ID_ENGINEER_MODE_AUDIO_CALIBRATION);
    lv_obj_add_style(title, LV_LABEL_PART_MAIN, &lv_watch_font30);
    lv_obj_align(title, NULL, LV_ALIGN_IN_TOP_MID, 0, 5);

    lv_obj_t * list = lv_list_create(obj, NULL);
    lv_obj_set_size(list, LV_HOR_RES, LV_VER_RES - lv_obj_get_height(title) - 10);
    lv_page_set_edge_flash(list, true);
    lv_obj_add_style(list, LV_LIST_PART_EDGE_FLASH, &lv_watch_cont_opa1);
    lv_obj_align(list, title, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);

    lv_engineer_main_obj_ext_t * ext = engineer_mode_get_ext();
    lv_obj_add_style(list, LV_LIST_PART_BG, &lv_watch_style_transp);

    uint8_t i = 0;
    lv_obj_t * btn;
    lv_obj_t * label;
    for(i = 0; i < ENGINEER_MODE_AUDIO_CALIBRATION_LIST_CNT; i++) {
        btn = lv_list_add_btn(list, NULL, lv_lang_get_text(engineer_mode_audio_calibration_list[i].txtId));
        lv_watch_set_free_num(btn, i);
        lv_obj_add_style(btn, LV_BTN_PART_MAIN, &(ext->list_btn_st));
        lv_obj_set_event_cb(btn, audio_calibration_btn_rel_event_cb);

        label = lv_obj_get_child(btn, NULL);
        lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
        lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
        lv_obj_set_width(label, LV_HOR_RES - 10);
    }

    lv_obj_set_click(list, true);

    return obj;
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
static lv_engineer_audio_calibration_obj_ext_t * audio_calibration_get_ext(void)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_ENGINEER_MODE_AUDIO_CALIBRATION);

    //printf("%s watch_obj %p\n", __FUNCTION__, activity_obj);

    if(activity_obj) {
        lv_engineer_audio_calibration_obj_ext_t * ext = lv_obj_get_ext_attr(activity_obj);
        return ext;
    }

    return NULL;
}

static void audio_calibration_btn_rel_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e) {
        uint32_t num = lv_obj_get_user_data(btn).user_num;
        lv_obj_t * obj = NULL;

        obj = engineer_mode_item_watch_obj_create(NULL, engineer_mode_audio_calibration_list[num].item_prepare_destory);
        if(NULL == obj) {
            printf("%s: obj is null\n", __FUNCTION__);
        } else {
            engineer_mode_item_title_create(obj, engineer_mode_audio_calibration_list[num].txtId);
            engineer_mode_audio_calibration_list[num].item_content_create(obj);
        }
    }
}

static void audio_calibration_prepare_destory(lv_obj_t * activity_obj)
{
    lv_watch_png_cache_all_free();
}

static void recording_test_create(lv_obj_t * par)
{
    lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();

    lv_obj_t * label = lv_label_create(par, NULL);
    lv_label_set_text_id(label, WATCH_TEXT_ID_READY);
    lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
    lv_obj_set_width(label, LV_HOR_RES);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 35);
    audio_ext->label_store = label;

    lv_obj_t * start_btn = lv_btn_create(par, NULL);
    lv_obj_set_size(start_btn, LV_HOR_RES * 2 / 5, 30);
    lv_obj_set_style_local_radius(start_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 5);
    lv_obj_t * start_label = lv_label_create(start_btn, NULL);
    lv_label_set_text_id(start_label, WATCH_TEXT_ID_START);
    lv_obj_add_style(start_label, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_obj_align(start_btn, NULL, LV_ALIGN_IN_TOP_LEFT, 15, 120);
    lv_obj_add_protect(start_btn, LV_PROTECT_PRESS_LOST);
    lv_obj_set_event_cb(start_btn, recording_start_btn_event_cb);
    lv_watch_obj_add_element(start_btn);

    lv_obj_t * stop_btn = lv_btn_create(par, NULL);
    lv_obj_set_size(stop_btn, LV_HOR_RES * 2 / 5, 30);
    lv_obj_set_style_local_radius(stop_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 5);
    lv_obj_t * stop_label = lv_label_create(stop_btn, NULL);
    lv_label_set_text_id(stop_label, WATCH_TEXT_ID_STOP);
    lv_obj_add_style(stop_label, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_obj_align(stop_btn, NULL, LV_ALIGN_IN_TOP_RIGHT, -15, 120);
    lv_obj_add_protect(stop_btn, LV_PROTECT_PRESS_LOST);
    lv_obj_set_event_cb(stop_btn, recording_stop_btn_event_cb);
    lv_watch_obj_add_element(stop_btn);

    lv_obj_t * play_btn = lv_btn_create(par, NULL);
    lv_obj_set_size(play_btn, LV_HOR_RES * 2 / 5, 30);
    lv_obj_set_style_local_radius(play_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 5);
    lv_obj_t * play_label = lv_label_create(play_btn, NULL);
    lv_label_set_text_id(play_label, WATCH_TEXT_ID_PLAY);
    lv_obj_add_style(play_label, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_obj_align(play_btn, NULL, LV_ALIGN_IN_TOP_LEFT, 15, 180);
    lv_obj_add_protect(play_btn, LV_PROTECT_PRESS_LOST);
    lv_obj_set_event_cb(play_btn, recording_play_btn_event_cb);
    lv_watch_obj_add_element(play_btn);

    lv_obj_t * end_btn = lv_btn_create(par, NULL);
    lv_obj_set_size(end_btn, LV_HOR_RES * 2 / 5, 30);
    lv_obj_set_style_local_radius(end_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 5);
    lv_obj_t * end_label = lv_label_create(end_btn, NULL);
    lv_label_set_text_id(end_label, WATCH_TEXT_ID_END);
    lv_obj_add_style(end_label, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_obj_align(end_btn, NULL, LV_ALIGN_IN_TOP_RIGHT, -15, 180);
    lv_obj_add_protect(end_btn, LV_PROTECT_PRESS_LOST);
    lv_obj_set_event_cb(end_btn, recording_end_btn_event_cb);
    lv_watch_obj_add_element(end_btn);
}

static void recording_start_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e) {
        lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();
        if(true == audio_ext->play_ongoing) {
            printf("%s: file playing is in progress.\n", __FUNCTION__);
        } else if(true == audio_ext->record_ongoing) {
            printf("%s: file recording is in progress.\n", __FUNCTION__);
        } else {
            lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_RECORDING);
            audio_ext->file_size = 0;
            audio_ext->record_ongoing = true;
            Hal_File_Record_Start_Req(AUDIO_CALIBRATION_RECORD_FILE, recording_test_record_cb);
        }
    }
}

static void recording_stop_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e) {
        lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();
        if(true == audio_ext->play_ongoing) {
            printf("%s: file playing is in progress.\n", __FUNCTION__);
        } else if(true == audio_ext->record_ongoing) {
            audio_ext->record_ongoing = false;
            if(MCI_ERR_ERROR == Hal_File_Record_Stop_Req(&audio_ext->file_size)) {
                lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_RECORD_ERROR);
                audio_ext->file_size = 0;
            } else {
                lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_RECORD_OVER);
            }
        } else if(0 == audio_ext->file_size) {
            lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_NOT_RECORD);
        }
    }
}

static void recording_play_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e) {
        lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();
        if(true == audio_ext->record_ongoing) {
            printf("%s: file recording is in progress.\n", __FUNCTION__);
        } else if(true == audio_ext->play_ongoing) {
            printf("%s: file playing is in progress.\n", __FUNCTION__);
        } else if(0 == audio_ext->file_size) {
            lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_NOT_RECORD);
        } else {
            lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_PLAYING);
            audio_ext->play_ongoing = true;
            Hal_NFFS_File_Play_Onetime(AUDIO_CALIBRATION_RECORD_FILE,
                                       query_current_volume(),
                                       audio_calibration_record_file_over_cb,
                                       NULL);
        }
    }
}

static void recording_end_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e) {
        lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();
        if(true == audio_ext->record_ongoing) {
            printf("%s: file recording is in progress.\n", __FUNCTION__);
        } else if(true == audio_ext->play_ongoing) {
            lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_PLAY_OVER);
            audio_ext->play_ongoing = false;
            Hal_NFFS_File_Play_End();
        } else if(0 == audio_ext->file_size) {
            lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_NOT_RECORD);
        } else {
            lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_NOT_PLAY);
        }
    }
}

static void recording_test_prepare_destory(lv_obj_t * activity_obj)
{
    lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();
    lv_watch_png_cache_all_free();
    Hal_File_Play_End();
    lv_obj_del(audio_ext->label_store);
    audio_ext->file_size = 0;
    audio_ext->record_ongoing = false;
    audio_ext->play_ongoing = false;
    lv_fs_remove(AUDIO_CALIBRATION_RECORD_FILE);
}

static void recording_test_record_cb(MCI_EVNET_T event, MCI_INFO_T info_type, int32_t value)
{
    printf("%s: event %d, type %d, value %d\n", __FUNCTION__, event, info_type, value);

    lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();
    if(NULL == audio_ext) {
        return;
    }

    if(MCI_EVENT_ERROR == event) {
        lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_RECORD_ERROR);
        Hal_File_Record_Stop_Req(&audio_ext->file_size);
        audio_ext->record_ongoing = false;
        audio_ext->file_size = 0;
    }
}

static void audio_calibration_record_file_over_cb(void * para)
{
    printf("%s\n", __FUNCTION__);
    lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();
    lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_PLAY_OVER);
    audio_ext->play_ongoing = false;
    Hal_NFFS_File_Play_End();
    //lv_fs_remove(AUDIO_CALIBRATION_RECORD_FILE);
}

static void playback_test_create(lv_obj_t * par)
{
    lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();

    lv_obj_t * label = lv_label_create(par, NULL);
    lv_label_set_text_id(label, WATCH_TEXT_ID_READY);
    lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
    lv_obj_set_width(label, LV_HOR_RES);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 35);
    audio_ext->label_store = label;

    lv_obj_t * start_btn = lv_btn_create(par, NULL);
    lv_obj_set_size(start_btn, LV_HOR_RES * 2 / 5, 30);
    lv_obj_set_style_local_radius(start_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 5);
    lv_obj_t * start_label = lv_label_create(start_btn, NULL);
    lv_label_set_text_id(start_label, WATCH_TEXT_ID_PLAY);
    lv_obj_add_style(start_label, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_obj_align(start_btn, NULL, LV_ALIGN_IN_TOP_LEFT, 15, 140);
    lv_obj_add_protect(start_btn, LV_PROTECT_PRESS_LOST);
    lv_obj_set_event_cb(start_btn, playback_start_btn_event_cb);
    lv_watch_obj_add_element(start_btn);

    lv_obj_t * stop_btn = lv_btn_create(par, NULL);
    lv_obj_set_size(stop_btn, LV_HOR_RES * 2 / 5, 30);
    lv_obj_set_style_local_radius(stop_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 5);
    lv_obj_t * stop_label = lv_label_create(stop_btn, NULL);
    lv_label_set_text_id(stop_label, WATCH_TEXT_ID_END);
    lv_obj_add_style(stop_label, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_obj_align(stop_btn, NULL, LV_ALIGN_IN_TOP_RIGHT, -15, 140);
    lv_obj_add_protect(stop_btn, LV_PROTECT_PRESS_LOST);
    lv_obj_set_event_cb(stop_btn, playback_stop_btn_event_cb);
    lv_watch_obj_add_element(stop_btn);
}

static void playback_start_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e) {
        lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();
        if(false == audio_ext->play_ongoing) {
            lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_PLAYING);
            audio_ext->play_ongoing = true;
            Hal_NFFS_File_Play_Onetime(AUDIO_INCOMING_CALL,
                                       query_current_volume(),
                                       audio_calibration_music_over_cb,
                                       NULL);
        } else {
            printf("%s: music has been played\n", __FUNCTION__);
        }
    }
}

static void playback_stop_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e) {
        lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();
        if(false == audio_ext->play_ongoing) {
            lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_NOT_PLAY);
        } else {
            lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_PLAY_OVER);
            audio_ext->play_ongoing = false;
            Hal_NFFS_File_Play_End();
        }
    }
}

static void audio_calibration_music_over_cb(void * para)
{
    printf("%s\n", __FUNCTION__);
    lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();
    lv_label_set_text_id(audio_ext->label_store, WATCH_TEXT_ID_PLAY_OVER);
    audio_ext->play_ongoing = false;
    Hal_NFFS_File_Play_End();
}

static void playback_test_prepare_destory(lv_obj_t * activity_obj)
{
    lv_engineer_audio_calibration_obj_ext_t * audio_ext = audio_calibration_get_ext();

    lv_watch_png_cache_all_free();
    Hal_NFFS_File_Play_End();
    audio_ext->play_ongoing = false;
    lv_obj_del(audio_ext->label_store);
}

#endif /*USE_LV_WATCH_ENGINEER_MODE*/
